package xbuf

import (
	"gitee.com/shuohe/xutils/xerror"
	"io/ioutil"
	"os"
)

type IMarshalable interface {
	// 将对象序列化到 XBuf 缓冲中
	MarshalToXBuf(*Buffer)
}

type IUnmarshalable interface {
	// 从 XBuf 缓冲中读取并还原出对象
	UnmarshalFromXBuf(*Buffer) error
}

/**
 * 将一个可 XBuf 序列化的对象存储到文件中。
 */
func SaveToFile(obj IMarshalable, fileName string) error {
	f, err := os.Create(fileName)
	if err != nil {
		return xerror.Wrapf(err, "Can not create file '%s'.", fileName)
	}

	xb := New(4096)
	obj.MarshalToXBuf(xb)

	_, err = f.Write(xb.Bytes())
	if err != nil {
		f.Close()
		os.Remove(fileName)
		return xerror.Wrap(err, "I/O error.")
	}

	return xerror.Wrapf(f.Close(), "I/O error.")
}

/*
 * 从文件中读取一个可 XBuf 序列化的对象。
 */
func LoadFromFile(obj IUnmarshalable, fileName string) error {
	data, err := ioutil.ReadFile(fileName)
	if err != nil {
		return xerror.Wrapf(err, "Can not read file '%s'.", fileName)
	}

	xb := WrapForRead(data)
	if err := obj.UnmarshalFromXBuf(xb); err != nil {
		return xerror.Wrap(err, "Unmarshal file data failed.")
	}

	return nil
}
